package com.gitee.feizns.quickstart.ding.talk.api.v10.oauth2;

import com.aliyun.dingtalkoauth2_1_0.Client;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponseBody;
import com.gitee.feizns.quickstart.ding.talk.Config;
import com.gitee.feizns.quickstart.ding.talk.client.Clients;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

/**
 * 企业内部应用accessToken
 *
 * /v1.0/oauth2/accessToken
 *
 * @link 钉钉文档链接 -> <a href="https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-an-internal-app">获取企业内部应用的accessToken</a>
 * @author feizns
 * @since 2023/09/12
 */
@RequiredArgsConstructor
public class AccessToken {

    /**
     * 配置信息
     */
    private final Config config;

    /**
     * access_token过期时间
     */
    private long expiredTime;

    /**
     * 缓存的access_token
     */
    private String accessToken;

    /**
     * 是否是已过期或空
     * @return boolean
     */
    public boolean isExpiredOrNull() {
        return accessToken == null || expiredTime <= System.currentTimeMillis();
    }

    /**
     * 获取token
     * @link 钉钉文档链接 -> <a href="https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-an-internal-app">获取企业内部应用的accessToken</a>
     * @apiNote 新版Api
     * @return access_token
     */
    @SneakyThrows
    public String get() {
        if ( isExpiredOrNull() ) {
            synchronized (this) {
                if ( isExpiredOrNull() ) {
                    Client client = Clients.get(Client.class);
                    GetAccessTokenRequest request = new GetAccessTokenRequest();
                    request.setAppKey(config.getAppKey());
                    request.setAppSecret(config.getAppSecret());
                    GetAccessTokenResponseBody body = client.getAccessToken(request).getBody();
                    expiredTime = System.currentTimeMillis() + body.getExpireIn();
                    accessToken = body.getAccessToken();
                }
            }
        }
        return accessToken;
    }

}